
#ifndef __XB_CPU_PENTIUM3_H__
#define __XB_CPU_PENTIUM3_H__

/* ------------------------------------------------------------------------- */

/* 32-bits general registers */
#define eax						reg[0]
#define ecx						reg[1]
#define edx						reg[2]
#define	ebx						reg[3]
#define esp						reg[4]
#define ebp						reg[5]
#define esi						reg[6]
#define edi						reg[7]

/* 16-bits general registers */
#define ax						(*(reg16_t *)(&reg[0]))
#define cx						(*(reg16_t *)(&reg[1]))
#define dx						(*(reg16_t *)(&reg[2]))
#define bx						(*(reg16_t *)(&reg[3]))
#define sp						(*(reg16_t *)(&reg[4]))
#define bp						(*(reg16_t *)(&reg[5]))
#define si						(*(reg16_t *)(&reg[6]))
#define di						(*(reg16_t *)(&reg[7]))

/* 8-bits general registers */
#define al						(*(reg8_t *)(&reg[0]))
#define cl						(*(reg8_t *)(&reg[1]))
#define dl						(*(reg8_t *)(&reg[2]))
#define bl						(*(reg8_t *)(&reg[3]))
#define ah						(*(reg8_t *)(&reg[4]))
#define ch						(*(reg8_t *)(&reg[5]))
#define dh						(*(reg8_t *)(&reg[6]))
#define bh						(*(reg8_t *)(&reg[7]))

/* other 8086 16-bits registers */
#define ip						(*(reg16_t *)(&eip))
#define flags					(*(reg16_t *)(&eflags))

/* segment registers (selector) */
#define es						sreg[0]
#define cs						sreg[1]
#define ss						sreg[2]
#define ds						sreg[3]
#define fs						sreg[4]
#define gs						sreg[5]

/* segment registers (descriptor) */
#define xes						xsreg[0]
#define xcs						xsreg[1]
#define xss						xsreg[2]
#define xds						xsreg[3]
#define xfs						xsreg[4]
#define xgs						xsreg[5]

/* control registers */
#define cr0						crx[0]
#define cr1						crx[1]
#define cr2						crx[2]
#define cr3						crx[3]
#define cr4						crx[4]

/* debug registers */
#define dr0						drx[0]
#define dr1						drx[1]
#define dr2						drx[2]
#define dr3						drx[3]
#define dr4						drx[4]
#define dr5						drx[5]
#define dr6						drx[6]
#define dr7						drx[7]

/* x87 float registers */
#define st(n)					stx[n]

/* MMX registers */
#define mm0						stx[0]
#define mm1						stx[1]
#define mm2						stx[2]
#define mm3						stx[3]
#define mm4						stx[4]
#define mm5						stx[5]
#define mm6						stx[6]
#define mm7						stx[7]

/* SSE registers */
#define xmm0					xmm[0]
#define xmm1					xmm[1]
#define xmm2					xmm[2]
#define xmm3					xmm[3]
#define xmm4					xmm[4]
#define xmm5					xmm[5]
#define xmm6					xmm[6]
#define xmm7					xmm[7]

#define FLAG_CF					0x00000001				/* carry flag */
#define FLAG_PF					0x00000004				/* parity flag */
#define FLAG_AF					0x00000010				/* auxiliary carry flag */
#define FLAG_ZF					0x00000040				/* zero flag */
#define FLAG_SF					0x00000080				/* sign flag */
#define FLAG_TF					0x00000100				/* trap flag */
#define FLAG_IF					0x00000200				/* interrupt enable flag */
#define FLAG_DF					0x00000400				/* direction flag */
#define FLAG_OF					0x00000800				/* overflow flag */
#define FLAG_IOPL				0x00003000				/* I/O privilege level */
#define FLAG_NT					0x00004000				/* nested task flag */
#define FLAG_RF					0x00010000				/* resume flag */
#define FLAG_VM					0x00020000				/* virtual-8086 mode */
#define FLAG_AC					0x00040000				/* alignment check */
#define FLAG_VIF				0x00080000				/* virtual interrupt flag */
#define FLAG_VIP				0x00100000				/* virtual interrupt pending */
#define FLAG_ID					0x00200000				/* identification flag */

#define CR0_PE					0x00000001				/* protection enable */
#define CR0_MP					0x00000002				/* monitor coprocessor */
#define CR0_EM					0x00000004				/* emulation */
#define CR0_TS					0x00000008				/* task switched */
#define CR0_ET					0x00000010				/* extension type */
#define CR0_NE					0x00000020				/* numeric error */
#define CR0_WP					0x00010000				/* write protect */
#define CR0_AM					0x00040000				/* alignment mask */
#define CR0_NW					0x20000000				/* not write-through */
#define CR0_CD					0x40000000				/* cache disable */
#define CR0_PG					0x80000000				/* paging */

#define CR3_PCD					0x00000010				/* page-level cache disable */
#define CR3_PWT					0x00000008				/* page-level writes transparent */
#define CR3_PDB					0xfffff000				/* page-directory base address */

#define CR4_VME					0x00000001				/* virtual-8086 mode extensions */
#define CR4_PVI					0x00000002				/* protected-mode virtual interrupts */
#define CR4_TSD					0x00000004				/* time stamp disable */
#define CR4_DE					0x00000008				/* debugging extensions */
#define CR4_PSE					0x00000010				/* page size extensions */
#define CR4_PAE					0x00000020				/* physical address extension */
#define CR4_MCE					0x00000040				/* machine-check enable */
#define CR4_PGE					0x00000080				/* page global enable */
#define CR4_PCE					0x00000100				/* performance-monitoring counter enable */
#define CR4_OSFXSR				0x00000200				/* operating sytsem FXSAVE/FXRSTOR support */
#define CR4_OSXMMEXCPT			0x00000400				/* operating system unmasked exception support */

#define DR7_GD					0x00001000				/* general detect enable */

#define DESC_A					0x0000010000000000		/* accessed (for data-segment and code-segment) */
#define DESC_W					0x0000020000000000		/* writable (for data-segment only) */
#define DESC_E					0x0000040000000000		/* expansion direction (for data-segment only) */
#define DESC_R					0x0000020000000000		/* readable (for code-segment only) */
#define DESC_B					0x0000020000000000		/* busy (for tss only) */
#define DESC_C					0x0000040000000000		/* conforming (for code-segment only) */
#define DESC_T					0x0000080000000000		/* code-segment or data-segment? (when S=1; 0 = data-segment; 1 = code-segment) */
#define DESC_P					0x0000800000000000		/* segment present */
#define DESC_S					0x0000100000000000		/* descriptor type (0 = system; 1 = code or data) */
#define DESC_D					0x0040000000000000		/* default operation size (0 = 16-bit segment; 1 = 32-bit segment) */
#define DESC_G					0x0080000000000000		/* granularity */

#define PDE_P					0x00000001				/* present */
#define PDE_RW					0x00000002				/* read/write */
#define PDE_US					0x00000004				/* user/supervisor */
#define PDE_PWT					0x00000008				/* page-level write-through */
#define PDE_PCD					0x00000010				/* page-level cache disable */
#define PDE_A					0x00000020				/* accessed */
#define PDE_D					0x00000040				/* dirty */
#define PDE_PS					0x00000080				/* page size */
#define PDE_G					0x00000100				/* global */
#define PDE_PTB					0xfffff000				/* page-table base address */

#define PTE_P					0x00000001				/* present */
#define PTE_RW					0x00000002				/* read/write */
#define PTE_US					0x00000004				/* user/supervisor */
#define PTE_PWT					0x00000008				/* page-level write-through */
#define PTE_PCD					0x00000010				/* page-level cache disable */
#define PTE_A					0x00000020				/* accessed */
#define PTE_D					0x00000040				/* dirty */
#define PTE_G					0x00000100				/* global */
#define PTE_PB					0xfffff000				/* page base address */

#define sel_cpl(sel)			((sel) & 0x0003)
#define sel_rpl					sel_cpl
#define sel_type(sel)			((sel) & 0x0004)
#define sel_index(sel)			((sel) & 0xfff8)

#define get_flag(f)				(eflags & (f))
#define set_flag(f, b)			(void)((b) ? (eflags |= (f)) : (eflags &= ~(f)))

/* ------------------------------------------------------------------------- */

typedef int8					reg8_t;
typedef int16					reg16_t;
typedef int32					reg32_t;
typedef int64					reg48_t;
typedef int64					reg64_t;
typedef float80					reg80_t;
typedef struct { int32 v[4]; }	reg128_t;

typedef struct {
	uint32 prev_link;
	uint32 esp0;
	uint32 ss0;
	uint32 esp1;
	uint32 ss1;
	uint32 esp2;
	uint32 ss2;
	uint32 pdbr;
	uint32 eip;
	uint32 eflags;
	uint32 reg[8];
	uint32 sreg[6];
	uint32 ldt;
	uint16 trace;
	uint16 io_map;
} tss_t;

/* ------------------------------------------------------------------------- */

/* 80386 application registers */
capi reg32_t reg[8];
capi reg16_t sreg[6];
capi reg64_t xsreg[6];
capi reg32_t eflags, eip;

/* 80386 system registers */
capi reg32_t crx[5];
capi reg32_t drx[8];
capi reg48_t gdtr, idtr;
capi reg16_t tr, ldtr;
capi reg64_t xtr, xldtr;

/* FPU/MMX registers */
capi reg80_t stx[8];

/* SSE registers */
capi reg32_t mxcsr;
capi reg128_t xmm[8];

/* MSR registers */
capi reg64_t tsc;

/* ------------------------------------------------------------------------- */

capi void reset_piii(void);
capi void start_piii(void);
capi void resume_piii(void);

/* ------------------------------------------------------------------------- */

#endif
